﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using RestService.Models;
using System.Drawing;
using System.Media;

namespace RestService
{
    public class GameLogic
    {
        DataConnection dataConn = null;
        string team = null;
        // do dobierania odległości
        int valueToFlag = 200;
        int valueToPlayer = 50;

        public bool action(string playerID, string gameID, string latitude, string longitude, DataConnection dataConn)
        {
            this.dataConn = dataConn;
            if (!ifIAmOutOFFArea_2(gameID, latitude, longitude, dataConn))
            {
                dataConn.TakeFlag(playerID);
                return true;
            }

            team = dataConn.getPlayerTeam(playerID);

            bool t = DoIgetAFlagAndPoint(gameID, playerID, latitude, longitude);
            if(!t)
                isSomebodyTakeMyFlag(playerID, gameID, latitude, longitude);

            return false;
        }

        public bool DoIgetAFlagAndPoint(string gameId, string playerId, string latitude1, string longitude1)
        {
            Area area = dataConn.getGameArea(gameId);
            // team a TRUE
            if (team.Equals("True"))
            {
                //Zabieram flage z bazy wroga
                if (CompareTwoPoints(int.Parse(latitude1), int.Parse(longitude1), int.Parse(area.latitude_area_a), int.Parse(area.longitude_area_a)))
                {
                    dataConn.SetFlag(playerId);
                    return true;
                }else
                //doszedlem do bazy z flagą
                if (dataConn.HasPlayerFlag(playerId) && CompareTwoPoints(int.Parse(latitude1), int.Parse(longitude1), int.Parse(area.latitude_area_c), int.Parse(area.longitude_area_c)))
                {
                    var points = dataConn.getPoints(gameId, playerId);
                    dataConn.TakeFlag(playerId);
                    string pointToWin = dataConn.howManyPointsToWin(gameId);
                    if (int.Parse(points) == int.Parse(pointToWin)-1)
                        points = (-2).ToString();
                    dataConn.SetPoint(gameId, team, points);
                    return true;
                }
            }
            // team b
            else
            {
                //Zabieram flage z bazy wroga
                if (CompareTwoPoints(int.Parse(latitude1), int.Parse(longitude1), int.Parse(area.latitude_area_c), int.Parse(area.longitude_area_c)))
                {
                    dataConn.SetFlag(playerId);
                    return true;
                }else
                //doszedlem do bazy z flagą
                if (dataConn.HasPlayerFlag(playerId) && CompareTwoPoints(int.Parse(latitude1), int.Parse(longitude1), int.Parse(area.latitude_area_a), int.Parse(area.longitude_area_a)))
                {
                    var points = dataConn.getPoints(gameId, playerId);
                    dataConn.TakeFlag(playerId);
                    string pointToWin = dataConn.howManyPointsToWin(gameId);
                    if (int.Parse(points) == int.Parse(pointToWin)-1)
                        points = (-3).ToString();
                    dataConn.SetPoint(gameId, team, points);
                    return true;
                }
            }
            return false;
        }

        public bool CompareTwoPoints(int lat1, int lon1, int lat2, int lon2)
        {
            Double a = (double)Math.Abs(lat1 - lat2);
            Double b = (double)Math.Abs(lon1 - lon2);
            Double c = Math.Abs((a * a) - (b * b));
            c = (int)Math.Sqrt(c);
            if (valueToFlag >= c )
                return true;
            else
                return false;
        }

        public bool CompareTwoPlayers(int lat1, int lon1, int lat2, int lon2)
        {
            Double a = (double)Math.Abs(lat1 - lat2);
            Double b = (double)Math.Abs(lon1 - lon2);
            Double c = Math.Abs((a * a) - (b * b));
            c = (int)Math.Sqrt(c);
            if (valueToPlayer >= c)
                return true;
            else
                return false;
        }

        public void isSomebodyTakeMyFlag(string playerID, string gameID, string latitude1, string longitude1)
        {
            if (team.Equals("True"))
                team = "False";
            else
                team = "True";

            List<FlagControll> fc = dataConn.getPlayersForFlagControl(gameID, playerID, team);
            Boolean looseFlag = false;
            foreach (FlagControll i in fc)
            {
                if (CompareTwoPlayers(int.Parse(latitude1), int.Parse(longitude1), i.latitude, i.longitude))
                {
                    looseFlag = true;
                    break;
                }
            }

            if (looseFlag)
            {
                dataConn.TakeFlag(playerID); ;
            }

        }

        public bool ifIAmOutOFFArea_2(string gameID, string latitude, string longitude, DataConnection dataConn)
        {
            Area ar = dataConn.getGameArea(gameID);

            int[] polyX = new int[4];
            int[] polyY = new int[4];
            int x = Convert.ToInt32(latitude);
            int y = Convert.ToInt32(longitude);

            polyY[0] = (Convert.ToInt32(ar.longitude_area_a));
            polyX[0] = (Convert.ToInt32(ar.latitude_area_a));

            polyY[1] = (Convert.ToInt32(ar.longitude_area_b));
            polyX[1] = (Convert.ToInt32(ar.latitude_area_b));

            polyY[2] = (Convert.ToInt32(ar.longitude_area_c));
            polyX[2] = (Convert.ToInt32(ar.latitude_area_c));

            polyY[3] = (Convert.ToInt32(ar.longitude_area_d));
            polyX[3] = (Convert.ToInt32(ar.latitude_area_d));

            List<Point> PolyPoints = new List<Point>();
            PolyPoints.Add(new Point(polyX[0], polyY[0]));
            PolyPoints.Add(new Point(polyX[1], polyY[1]));
            PolyPoints.Add(new Point(polyX[2], polyY[2]));
            PolyPoints.Add(new Point(polyX[3], polyY[3]));

            return IsPointInPolygon(PolyPoints, new Point(x,y));
        }

        public static bool IsPointInPolygon(List<Point> polygon, Point testPoint)
        {
            bool result = false;
            int i = 0, j = 0;
            for (i = 0, j = polygon.Count - 1; i < polygon.Count; j = i++)
            {
                if (((polygon[i].Y > testPoint.Y) != (polygon[j].Y > testPoint.Y)) &&
                 (testPoint.X < (polygon[j].X - polygon[i].X) * (testPoint.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X))
                    result = !result;
            }
            return result;
        }

 
    }
}